#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>

#include <nng/nng.h>
#include <nng/protocol/pubsub0/pub.h>

#define PROXY_FRONT_URL "tcp://localhost:3327"
// #define PROXY_BACK_URL "tcp://localhost:3328"

static void
fatal(const char *msg, ...)
{
	va_list ap;
	va_start(ap, msg);
	vfprintf(stderr, msg, ap);
	va_end(ap);
	fprintf(stderr, "\n");
	exit(1);
}



void sendloop_new(nng_socket sock) {
	const char* data_template = "This is data to send: A message from behind the Great Wall.";

	//strlen(data)

	size_t datalen = 0;

	uint32_t counter = 0;

	for (;;) {
		int          rv;
		nng_msg* msg;

		std::stringstream ss;
		ss << data_template << " " << (counter++);
		std::string data_str = ss.str();
		const char * data = data_str.c_str();
		datalen = data_str.size();

		if (((rv = nng_msg_alloc(&msg, 0)) != 0) ||
			((rv = nng_msg_append(msg, data, datalen)) != 0)) {
			fatal(nng_strerror(rv));
		}

		if ((rv = nng_sendmsg(sock, msg, 0)) != 0) {
			fatal("Send error: %s", nng_strerror(rv));
		}

		nng_msleep(500);

	}

	// Wait a bit to give queues a chance to drain when the program exits.
	nng_msleep(200);
}







int
main()
{
	nng_socket sock = NNG_SOCKET_INITIALIZER;
	int        ret            = 0;

	//
	//  First we need some nng sockets. Not to be confused with network
	//  sockets
	//
	ret = nng_pub0_open(&sock);
	if (ret) {
		fatal("Failed to open socket: %s\n", nng_strerror(ret));
	}

	//
	//  Now we need to set up a listener for each socket so that they have
	//  addresses
	//

	{
		int rv = 0;
		nng_dialer d;
		int async = 0;

		rv = nng_dialer_create(&d, sock, PROXY_FRONT_URL);
		if (rv != 0) {
			fatal("Unable to create dialer for %s: %s",
				  PROXY_FRONT_URL, nng_strerror(rv));
		}
		
		
		rv  = nng_dialer_start(d, async);
		if ((rv == 0)) {
			char   ustr[256];
			size_t sz;
			sz = sizeof(ustr);
			if (nng_dialer_getopt(
					d, NNG_OPT_URL, ustr, &sz) == 0) {
				printf("Connected to: %s\n", ustr);
			}
		}
	}

	//
	//  Finally let nng do the forwarding/proxying
	//

	// ret = nng_device(sock_front_end, sock_back_end);
	// panic_on_error(
	//     ret, "f-b nng_device returned %d: %s\n", ret, nng_strerror(ret));

	// sendloop(sock);

	sendloop_new(sock);

	printf("done");
	return 0;
}